package com.fishingwithme.infrastructure;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class CodeEnumDeserializer extends JsonDeserializer<CodeEnum> {
    // 缓存枚举类的 ofType 方法，避免重复反射调用
    private static final Map<Class<?>, Method> methodCache = new HashMap<>();

    @Override
    public CodeEnum deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        // 获取目标枚举类型
        Class<?> enumClass = ctxt.getContextualType() != null
                ? ctxt.getContextualType().getRawClass()
                : null;

        // 验证目标类型
        if (enumClass == null || !enumClass.isEnum() || !CodeEnum.class.isAssignableFrom(enumClass)) {
            return null;
           // throw new IOException("Unsupported type for CodeEnum deserialization: " + enumClass);
        }

        // 解析 JSON 内容
        ObjectMapper mapper = (ObjectMapper) p.getCodec();
        JsonNode node = mapper.readTree(p);

        // 处理 null 值
        if (node == null || node.isNull()) {
            return null;
        }

        // 提取 type 值
        Integer typeValue = extractTypeValue(node);
        if (typeValue == null) {
            throw new IOException("Missing 'type' field for enum deserialization");
        }

        try {
            // 使用缓存的方法或反射获取
            Method ofTypeMethod = methodCache.computeIfAbsent(enumClass, cls -> {
                try {
                    return cls.getMethod("ofType", int.class);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException("Method 'ofType' not found in " + cls.getName(), e);
                }
            });

            // 调用静态方法
            return (CodeEnum) ofTypeMethod.invoke(null, typeValue);
        } catch (Exception e) {
            // 记录详细错误信息
            String errorMsg = String.format("Failed to deserialize %s from value %d",
                    enumClass.getName(), typeValue);
            throw new IOException(errorMsg, e);
        }
    }

    /**
     * 从 JSON 节点中提取 type 值，支持多种格式
     */
    private Integer extractTypeValue(JsonNode node) {
        // 处理直接数值格式（如：1）
        if (node.isInt()) {
            return node.asInt();
        }

        // 处理对象格式（如：{"type": 1}）
        if (node.has("type")) {
            JsonNode typeNode = node.get("type");
            if (typeNode.isInt()) {
                return typeNode.asInt();
            }
        }

        // 处理字符串形式的数值（如："1"）
        if (node.isTextual()) {
            try {
                return Integer.parseInt(node.asText());
            } catch (NumberFormatException e) {
                return null;
            }
        }

        return null;
    }
}
